package server.control;

import java.awt.Rectangle;
import java.rmi.MarshalledObject;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import server.gui.ServerFrame;
import common.IClient;
import common.IServer;
import entity.Constants;
import entity.Fish;

public class ServerControl extends UnicastRemoteObject implements IServer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 154220555407187849L;
	
	public ArrayList<IClient> clients = new ArrayList<IClient>();
	public ArrayList<Fish> fishes = new ArrayList<Fish>();
	private ServerFrame serverGUI;
	
	public boolean isRunning = false;
	

	public ServerControl() throws RemoteException {
		super();
		
		serverGUI = new ServerFrame(clients, this);
	}

	@Override
	public boolean connect(IClient client) throws RemoteException {
		clients.add(client);
		
/////////////////set id to the client/////////////////////////////////////
		ArrayList<Integer> idRes = new ArrayList<Integer>() {			//
			/**															//
			 * 															//
			 */															//
			private static final long serialVersionUID = 1L;			//
			{add(1);}													//
			{add(2);}													//
			{add(3);}													//
		};																//
																		//
		for(IClient iclient : clients) {								//
			idRes.remove(new Integer(iclient.getId()));					//
		}																//
//////////////////////////////////////////////////////////////////////////
		client.setId(idRes.get(0));
		System.out.println(client.getId());
		
		//update client manager panel
		serverGUI.cmpanel.removeAll();
		serverGUI.cmpanel.emptyRowList();
		serverGUI.cmpanel.createNewRow();
		serverGUI.cmpanel.recreatePreRow();
		serverGUI.cmpanel.updateUI();

		return true;
	}

	@Override
	public ArrayList<Fish> updateClient(ArrayList<Fish> fesclient, int id) throws RemoteException {
		//update fishes array beside client
		
		//get client from clients array
		//get frame of client
		Rectangle frame = new Rectangle();
		ArrayList<Fish> tmpfishes = new ArrayList<Fish>(fishes);

			try {
				//System.out.println(id);
				frame = Constants.FRAMES.get(id - 1);
				
				Fish fish;
				for(int k = 0; k < tmpfishes.size(); k++) {

					fish = tmpfishes.get(k);
					
					if(((fish.x + fish.scale*fish.oWidth) >= frame.getMinX()) && (fish.x < frame.getMaxX())) {
						
						fish.isDraw = true;
					} else {
						
						fish.isDraw = false;
					}
				}
				
				return tmpfishes;
				
		} catch (Exception e) {
				e.printStackTrace();
			}
//		}
		return tmpfishes;

	}
	
	public void init() {
		
		//init fish beside server
		Fish fish;
		
		Random rand = new Random();
		
		
		for(int i = 0; i < serverGUI.fmpanel.fishRow.size(); i++) {
			
			if(serverGUI.fmpanel.fishRow.get(i).checkbox.isSelected()) {
				
				if(serverGUI.fmpanel.fishRow.get(i).tf.getText().equals("0")) {
					break;
				}
				for(int j = 0; j <Integer.parseInt(serverGUI.fmpanel.fishRow.get(i).tf.getText()); j++)
				{
					
					//init values
					int w = (int) Constants.DIM_FISHES[i][0];
					int h = (int) Constants.DIM_FISHES[i][1];
					int x = (int) (rand.nextFloat() * (Constants.PANEL_P_WIDTH));
					
					//init scale
					float s = rand.nextFloat();
					while (s < 0.3) {
						s += 0.4;
					}
					
					//init value of y coordinate of fish
					int bottom = Constants.PANEL_P_HEIGHT - h;
					int y = (int) (rand.nextFloat() * Constants.PANEL_P_HEIGHT);
					
					while((y > bottom)) {
						y -=  h;
					}
					
					//get path image
					String path = Constants.IMAGE_FISHES.get(i);
					
					//random index of speed array : 0, 1, 2
					int index;
					float value = rand.nextFloat();
					if(value < 0.3) {
						index = 0;
					} else if(value < 0.8) {
						index = 1;
					} else {
						index = 2;
					}
					
					//add fish to fishes array
					fish = new Fish(	serverGUI.fmpanel.fishRow.get(i).kind,
										serverGUI.fmpanel.fishRow.get(i).speed[index],
										x,
										y,
										w,
										h,
										s,
										path
									);
					fishes.add(fish);
					
				}
				
				//shuffle to ensure natural initialization
				Collections.shuffle(fishes, new Random(100));
				
				serverGUI.ppanel.fishes = fishes;
				
				for(int k = 0; k < clients.size(); k++) {
					try {
							
							MarshalledObject<ArrayList<Fish>> obj = new MarshalledObject<ArrayList<Fish>>(fishes);
							clients.get(k).setFishes(obj);
					} catch (Exception e) {
						
						continue;
						//e.printStackTrace();
					}
				}
			}
		}
	}
	
	public void update() {
		
		if(isRunning) {
			
			//update fishes array beside server
			for(int i = 0; i < fishes.size(); i++) {
				
				if(fishes.get(i).x > Constants.POOL_RECT.width) {
					fishes.get(i).x = (int) -(fishes.get(i).scale * fishes.get(i).oWidth);
				} else {
					fishes.get(i).x +=fishes.get(i).speed;
				}
			}
			
			serverGUI.ppanel.fishes = fishes;
		}
	}
	
	@Override
	public void notifyServer(IClient client) throws RemoteException {
		clients.remove(client);
		//update client manager panel
		serverGUI.cmpanel.removeAll();
		serverGUI.cmpanel.removeRow(client.getId());
		serverGUI.cmpanel.recreatePreRow();
		serverGUI.cmpanel.updateUI();
	}
	
	public void refreshCMPanel() {
		serverGUI.cmpanel.rows.removeAll(serverGUI.cmpanel.rows);
		serverGUI.cmpanel.createNewRow();
		serverGUI.cmpanel.removeAll();
		serverGUI.cmpanel.recreatePreRow();
		serverGUI.cmpanel.updateUI();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		try {
			
			ServerControl serverCtrl = new ServerControl();
			Naming.rebind("server", serverCtrl);		
			
			//System.out.println("server is ready");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
